package com.rustic.server.controller.api;

import cn.hutool.core.img.ImgUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import cn.xy.base.server.vo.LoginResult;
import cn.xy.commons.annotation.ApiAuth;
import cn.xy.commons.core.Result;
import cn.xy.commons.enums.YesNoStatus;
import cn.xy.third.sms.enums.CaptchaType;
import com.rustic.server.dto.user.CaptchaLoginDTO;
import com.rustic.server.dto.user.EmailDTO;
import com.rustic.server.dto.user.LoginDTO;
import com.rustic.server.dto.user.MobileDTO;
import com.rustic.server.po.User;
import com.rustic.server.service.CaptchaService;
import com.rustic.server.service.UserService;
import com.rustic.server.vo.user.UserSimpleVO;
import com.rustic.server.web.WebContext;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;

/**
 *  
 */

@Slf4j
@RestController
@RequestMapping("/api")
@Api(tags = {"前台登录接口"})
@ApiAuth(ignore = true)
public class IndexController {

    @Autowired
    private UserService userService;

    @Autowired
    private CaptchaService captchaService;

    @ApiOperation(value = "用户登录", notes = "登陆成功则携带token返回")
    @PostMapping("/login")
    public Result<LoginResult<UserSimpleVO>> login(@RequestBody @Validated LoginDTO loginDTO) {
        String ip = WebContext.getIp();
        User user = userService.getByMatch(loginDTO.getAccount());
        if (user == null) {
            return Result.error("账号或密码错误，请重新输入");
        }
        if (!user.getPassword().equals(userService.encodePassword(loginDTO.getPassword(), user.getSalt()))) {
            return Result.error("账号或密码错误，请重新输入");
        }
        if (YesNoStatus.isYes(user.getIsLock())) {
            return Result.error("用户已被禁止登录");
        }
        String token = userService.login(ip, user);
        UserSimpleVO account = userService.getSimpleById(user.getId());
        return Result.data(new LoginResult<>(token, account));
    }

    @ApiOperation(value = "发送注册验证码(短信)")
    @PostMapping("/sendRegisterCaptcha")
    public Result<String> sendRegisterCaptcha(@RequestBody @Validated MobileDTO mobileDTO) {
        User user = userService.getByMatch(mobileDTO.getMobile());
        if (user != null) {
            Result.error("手机号码已被使用");
        }
        captchaService.sendSmsCaptcha(CaptchaType.REGISTER, mobileDTO.getMobile());
        return Result.ok();
    }

    @ApiOperation(value = "发送注册验证码(邮件)")
    @PostMapping("/sendRegisterCaptchaByEmail")
    public Result<String> sendRegisterCaptcha(@RequestBody @Validated EmailDTO dto) {
        User user = userService.getByMatch(dto.getEmail());
        if (user != null) {
            Result.error("邮箱已被使用");
        }
        captchaService.sendEmailCaptcha(CaptchaType.REGISTER, dto.getEmail());
        return Result.ok();
    }

    @ApiOperation(value = "发送登陆验证码(短信)")
    @PostMapping("/sendLoginCaptcha")
    public Result<String> sendLoginCaptcha(@RequestBody @Validated MobileDTO mobileDTO) {
        User user = userService.getByMatch(mobileDTO.getMobile());
        if (user != null) {
            Result.error("账号未注册");
        }
        captchaService.sendSmsCaptcha(CaptchaType.REGISTER, mobileDTO.getMobile());
        return Result.ok();
    }

    @ApiOperation(value = "验证码登陆", notes = "登陆成功则携带token返回")
    @PostMapping("/captchaLogin")
    public Result<LoginResult<UserSimpleVO>> captchaLogin(@RequestBody @Validated CaptchaLoginDTO dto) {
        String ip = WebContext.getIp();
        User user = userService.getByMatch(dto.getAccount());
        if (user == null) {
            return Result.error("账号未注册");
        }
        // 检验验证码
        captchaService.checkCaptcha(CaptchaType.LOGIN, dto.getCaptcha(), dto.getAccount());
        if (YesNoStatus.isYes(user.getIsLock())) {
            return Result.error("用户已被禁止登录");
        }
        String token = userService.login(ip, user);
        UserSimpleVO account = userService.getSimpleById(user.getId());
        return Result.data(new LoginResult<>(token, account));
    }

    @ApiOperation(value = "验证码注册", notes = "登陆成功则携带token返回")
    @PostMapping("/register")
    public Result<LoginResult<UserSimpleVO>> register(@RequestBody @Validated CaptchaLoginDTO dto) {
        String ip = WebContext.getIp();
        dto.checkPassword();
        // 检验验证码
        captchaService.checkCaptcha(CaptchaType.REGISTER, dto.getCaptcha(), dto.getAccount());
        // 如果用户不存在直接注册
        User user = userService.addUserByAccount(dto.getAccount(), dto.getPassword(), ip, dto.getNationalityId());
        if (YesNoStatus.isYes(user.getIsLock())) {
            return Result.error("用户已被禁止登录");
        }
        String token = userService.login(ip, user);
        UserSimpleVO account = userService.getSimpleById(user.getId());
        return Result.data(new LoginResult<>(token, account));
    }

    @ApiOperation(value = "用户登出")
    @PostMapping("/logout")
    @ApiAuth(ignore = false)
    public Result<String> logout() {
        int userId = WebContext.getUserId();
        userService.logout(userId);
        return Result.ok();
    }

    @ApiOperation(value = "根据参数生成二维码，最大width不超过1024", notes = "根据参数生成二维码")
    @GetMapping("/qrcode")
    public void qrCode(String content,
                       @RequestParam(required = false, defaultValue = "200") int width,
                       @RequestParam(required = false, defaultValue = "1") int margin,
                       HttpServletResponse response) {
        width = width > 1024 ? 1024 : width;
        width = width < 0 ? 200 : width;

        margin = margin > 10 ? 10 : margin;
        margin = margin < 0 ? 1 : margin;

        QrConfig qrConfig = new QrConfig();
        qrConfig.setMargin(margin);
        qrConfig.setForeColor(new Color(0, 0, 0));
        qrConfig.setBackColor(new Color(255, 255, 255));
        qrConfig.setWidth(width);
        qrConfig.setHeight(width);
        try {
            QrCodeUtil.generate(content, qrConfig, ImgUtil.IMAGE_TYPE_JPG, response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
